#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "freertos/event_groups.h"
#include "driver/gpio.h"
#include "led.h"
#include "button.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "simple_wifi_sta.h"
#include "http.h"
#include "mqtt.h"
#include "cJSON.h"

static const char *TAG = "main";

// 按键事件组
static EventGroupHandle_t s_pressEvent;
#define SHORT_EV BIT0 // 短按
#define LONG_EV BIT1  // 长按
#define BTN_GPIO 0

/** 短按按键回调函数
 * @param 无
 * @return 无
 */
void short_press_handle(void)
{
    xEventGroupSetBits(s_pressEvent, SHORT_EV);
}
/** 长按按键回调函数
 * @param 无
 * @return 无
 */
void long_press_handle(void)
{
    xEventGroupSetBits(s_pressEvent, LONG_EV);
}
/** 完整的按键
 * @param 无
 * @return 无
 */
void complete_btn_test(void *arg)
{
    s_pressEvent = xEventGroupCreate();
    button_config_t btn_cfg =
        {
            .gpio_num = BTN_GPIO,           // gpio号
            .active_level = 0,              // 按下的电平
            .long_press_time = 3000,        // 长按时间
            .short_cb = short_press_handle, // 短按回调函数
            .long_cb = long_press_handle    // 长按回调函数
        };
    button_event_set(&btn_cfg); // 添加按键响应事件处理
    EventBits_t ev;
    while (1)
    {
        // 等待按键按下事件
        ev = xEventGroupWaitBits(s_pressEvent, SHORT_EV | LONG_EV, pdTRUE, pdFALSE, portMAX_DELAY);
        if (ev & SHORT_EV)
        {
            ESP_LOGI(TAG, "");
        }
        if (ev & LONG_EV)
        {
            wifi_prov_mgr_reset_provisioning(); // 重置配网状态
            led_flash_init();
        }
        xEventGroupClearBits(s_pressEvent, SHORT_EV);
        xEventGroupClearBits(s_pressEvent, LONG_EV);
    }
}

#define WIFI_CONNECT_BIT BIT0
static EventGroupHandle_t s_wifi_ev = NULL;

/** wifi事件通知
 * @param 无
 * @return 无
 */
void wifi_event_handler(WIFI_EV_e ev)
{
    if (ev == WIFI_CONNECTED)
    {
        xEventGroupSetBits(s_wifi_ev, WIFI_CONNECT_BIT);
    }
}
/** 启动weather_http
 * @param 无
 * @return 无
 */
void weather_http_task(void *arg)
{
    s_client_http_event = xEventGroupCreate();
    while (1)
    {
        EventBits_t ev = 0;
        // 一直监听WIFI连接事件，直到WiFi连接成功后，才发起天气请求
        ev = xEventGroupWaitBits(s_wifi_ev, WIFI_CONNECT_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
        if (ev & WIFI_CONNECT_BIT)
        {
            vTaskDelay(pdMS_TO_TICKS(2000));
            // 首先发起位置获取请求，成功后才去获取天气信息
            if (location_http_init() == ESP_OK)
                weather_http_init();
            xEventGroupClearBits(s_wifi_ev, WIFI_CONNECT_BIT);
        }
    }
}

/** 启动mqtt
 * @param 无
 * @return 无
 */
void mqtt_task(void *arg)
{
    EventBits_t ev = 0;
    // 一直监听WIFI连接事件，直到WiFi连接成功后，才启动MQTT连接
    ev = xEventGroupWaitBits(s_wifi_ev, WIFI_CONNECT_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
    if (ev & WIFI_CONNECT_BIT)
    {
        mqtt_start();
    }
    static char mqtt_pub_buff[64];
    while (1)
    {
        int count = 0;
        // 延时2秒发布一条消息到/test/topic1主题
        if (s_is_mqtt_connected)
        {
            snprintf(mqtt_pub_buff, 64, "{\"count\":\"%d\"}", count);
            esp_mqtt_client_publish(s_mqtt_client, MQTT_PUBLIC_TOPIC,
                                    mqtt_pub_buff, strlen(mqtt_pub_buff), 1, 0);
            count++;
        }

        vTaskDelay(pdMS_TO_TICKS(2000));
    }
}

void app_main(void)
{
    // led_breath_init(); // LED呼吸灯

    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        // NVS出现错误，执行擦除
        ESP_ERROR_CHECK(nvs_flash_erase());
        // 重新尝试初始化
        ESP_ERROR_CHECK(nvs_flash_init());
    }
    s_wifi_ev = xEventGroupCreate();

    wifi_sta_init(wifi_event_handler); // 初始化WIFI，传入回调函数，用于通知连接成功事件
    // 检查是否已配网
    bool provisioned = false;
    ESP_ERROR_CHECK(wifi_prov_mgr_is_provisioned(&provisioned));
    if (!provisioned)
    {
        ESP_LOGI(TAG, "未配网，启动配网模式");
        const char *pop = "abcd1234";
        wifi_prov_security1_params_t *wifi_prov_sec_params = pop;
        ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(WIFI_PROV_SECURITY_1, (void *)wifi_prov_sec_params, "PROV_Lctech", NULL));
        // wifi_prov_mgr_start_provisioning(WIFI_PROV_SECURITY_0,  NULL,"PROV_Lctech", NULL);
    }
    else
    {
        ESP_LOGI(TAG, "已配网，启动 Wi-Fi STA 模式");
        wifi_prov_mgr_deinit(); // 释放配网管理器资源
    }

    // 创建任务
    xTaskCreatePinnedToCore(complete_btn_test, "btn0", 4096, NULL, 3, NULL, 1);
    xTaskCreatePinnedToCore(weather_http_task, "weather_http_task", 4096, NULL, 15, NULL, 1);
    xTaskCreatePinnedToCore(mqtt_task, "mqtt_task", 4096, NULL, 17, NULL, 1);
}
